/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chatlink;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 *
 * @author Nguyen Van Thoi
 */
public class ChatRoom extends MyEvent {

    private JFrame _jChatForm;
    private JLabel _jlblUsername, _jlblPassword;
    private JMenuBar _jmnBar;
    private JMenu _jmnOption, _jmnFormat, _jmnStyle;
    private JMenuItem _jmnItemRegister, _jmnItemExit, _jmnItemForeColor, _jmnItemBgColor, _jmnItemMetal;
    private JScrollPane _jscrollChatcontent, _jscrollMessage, _jscrollLstOnline;
    private JTextArea _jtxtChatContent, _jtxtMessage;
    private JList<Object> _jlstOnline;
    private JButton _jbtnSend, _jbtnToggle;
    private JPanel _jPanel;
    private JTextField _jtxtUsername;
    private JPasswordField _jtxtPassword;
    private Socket _sck = null;
    private ObjectInputStream _ois = null;
    private ObjectOutputStream _oos = null;
    private final int PORT = 9999;
    private final String HOST = "localhost";
    private Thread t = null;

    public ChatRoom() {
        Initialization();
    }

    private void Initialization() {
        _jChatForm = new JFrame("Chat room");
        _jPanel = new JPanel();
        _jmnBar = new JMenuBar();

        _jmnOption = new JMenu("Option");
        _jmnOption.setMnemonic(KeyEvent.VK_O);
        _jmnFormat = new JMenu("Format");
        _jmnFormat.setMnemonic(KeyEvent.VK_F);

        _jmnItemBgColor = new JMenuItem("Background color");
        _jmnItemBgColor.setMnemonic(KeyEvent.VK_B);
        _jmnItemBgColor.addActionListener(this);

        _jmnItemForeColor = new JMenuItem("Text color");
        _jmnItemForeColor.setMnemonic(KeyEvent.VK_T);
        _jmnItemForeColor.addActionListener(this);

        _jmnStyle = new JMenu("Style");
        _jmnStyle.setMnemonic(KeyEvent.VK_S);

        _jmnItemMetal = new JMenuItem("Metal");
        _jmnItemMetal.setMnemonic(KeyEvent.VK_M);

        _jmnItemRegister = new JMenuItem("Register");
        _jmnItemRegister.setMnemonic(KeyEvent.VK_R);
        _jmnItemRegister.addActionListener(this);

        _jmnItemExit = new JMenuItem("Exit");
        _jmnItemExit.setMnemonic(KeyEvent.VK_E);
        _jmnItemExit.addActionListener(this);

        _jlblPassword = new JLabel("Password");
        _jlblUsername = new JLabel("Username");

        _jbtnToggle = new JButton("Login");
        _jbtnToggle.addActionListener(this);

        _jtxtUsername = new JTextField(10);
        _jtxtPassword = new JPasswordField(10);

        _jtxtChatContent = new JTextArea(22, 44);
        _jtxtChatContent.setWrapStyleWord(true);
        _jtxtChatContent.setLineWrap(true);
        _jtxtChatContent.setEditable(false);
        _jscrollChatcontent = new JScrollPane(_jtxtChatContent);

        _jtxtMessage = new JTextArea(6, 48);
        _jtxtMessage.setWrapStyleWord(true);
        _jtxtMessage.setLineWrap(true);
        _jscrollMessage = new JScrollPane(_jtxtMessage);

        _jlstOnline = new JList<>();
        _jscrollLstOnline = new JScrollPane(_jlstOnline);
        _jscrollLstOnline.setPreferredSize(new Dimension(160, 353));

        _jbtnSend = new JButton("Send");
        _jbtnSend.setPreferredSize(new Dimension(111, 99));
        _jbtnSend.addActionListener(this);
    }

    public void CreateGUI() {
        _jmnOption.add(_jmnItemRegister);
        _jmnOption.add(_jmnItemExit);
        _jmnFormat.add(_jmnItemBgColor);
        _jmnFormat.add(_jmnItemForeColor);
        _jmnStyle.add(_jmnItemMetal);
        _jmnFormat.add(_jmnStyle);

        _jmnBar.add(_jmnOption);
        _jmnBar.add(_jmnFormat);

        _jPanel.add(_jlblUsername);
        _jPanel.add(_jtxtUsername);
        _jPanel.add(_jlblPassword);
        _jPanel.add(_jtxtPassword);
        _jPanel.add(_jbtnToggle);

        _jPanel.add(_jscrollChatcontent);
        _jPanel.add(_jscrollLstOnline);
        _jPanel.add(_jscrollMessage);
        _jPanel.add(_jbtnSend);

        _jChatForm.add(_jPanel);
        _jChatForm.setJMenuBar(_jmnBar);
        _jChatForm.setSize(678, 560);
        _jChatForm.setResizable(false);
        _jChatForm.addWindowListener(this);
        _jChatForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        _jChatForm.setVisible(true);
    }

    public static void main(String[] args) {
        ChatRoom chatRoom = new ChatRoom();
        chatRoom.CreateGUI();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(_jmnItemExit)) {
            System.exit(1);
        } else if (e.getSource().equals(_jmnItemRegister)) {
            RegisterForm registerFrm = new RegisterForm();
            registerFrm.CreateGUI();
        } else if (e.getSource().equals(_jmnItemBgColor)) {
            _jtxtChatContent.setBackground(JColorChooser.showDialog(_jmnBar, "Chọn màu", Color.WHITE));
        } else if (e.getSource().equals(_jmnItemForeColor)) {
            _jtxtChatContent.setForeground(JColorChooser.showDialog(_jmnBar, "Chọn màu", Color.BLACK));
        } else if (e.getSource().equals(_jmnItemMetal)) {
            try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                Logger.getLogger(ChatRoom.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (e.getSource().equals(_jbtnSend)) {
            try {
                if (_sck != null) {
                    Message message = new Message();
                    message.setMessage(_jtxtUsername.getText() + ": " + _jtxtMessage.getText());
                    message.setStatus(MessageType.CHAT_MESSAGE);
                    StreamData.WriteObject(_oos, message);
                    _jtxtMessage.setText("");

                } else {
                    _jtxtChatContent.setText("Error: Bạn chưa đăng nhập!");

                }
            } catch (Exception exception) {

                JOptionPane.showMessageDialog(null, "Mất kết nối! Vui lòng đăng nhập lại!");
            }
        } else if (e.getSource().equals(_jbtnToggle)) {
            Message message = null;
            switch (e.getActionCommand()) {
                case "Login":
                    try {
                        if (_jtxtUsername.getText().isEmpty() || _jtxtPassword.getPassword().length == 0) {
                            _jtxtChatContent.setText("Bạn phải nhập đầy đủ thông tin!");
                            return;
                        }
                        _sck = new Socket(HOST, PORT);
                        _oos = new ObjectOutputStream(_sck.getOutputStream());
                        message = new Message();
                        message.setMessage("Login");
                        StreamData.WriteObject(_oos, message);

                        _ois = new ObjectInputStream(_sck.getInputStream());
                        message = (Message) StreamData.ReadObject(_ois);
                        message = null;

                        Account accountInfo = new Account();
                        accountInfo.setAccountId(_jtxtUsername.getText());
                        accountInfo.setPassword(PasswordUtility.getPassword(_jtxtPassword.getPassword()));
                        StreamData.WriteObject(_oos, accountInfo);

                        _jlstOnline.setListData((Object[]) _ois.readObject());

                        message = (Message) _ois.readObject();
                        switch (message.getStatus()) {
                            case LOGIN_SUCCESSFULLY:

                                _jtxtChatContent.setText(message.getMessage() + "\n");
                                _jtxtUsername.setEnabled(false);
                                _jtxtPassword.setEnabled(false);
                                _jbtnToggle.setText("Logout");

                                t = new ClientHandler();
                                t.start();
                                break;

                            case LOGIN_FAILED:
                            case USER_ONLINE:
                                _jtxtChatContent.setText(message.getMessage() + "\n");
                                _jtxtPassword.setText("");
                                break;
                        }
                    } catch (IOException | ClassNotFoundException exception) {
                        exception.printStackTrace();
                        JOptionPane.showMessageDialog(null, "Không thể kết nối tới máy chủ!");
                        _jtxtPassword.setText("");
                    }

                    break;

                case "Logout":
                    _jbtnToggle.setText("Login");
                    _jtxtPassword.setEnabled(true);
                    _jtxtUsername.setEnabled(true);
                    Signout();
                    break;
            }

        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        String user = (String) _jlstOnline.getSelectedValue();
        ChatPrivate chatPrivate = new ChatPrivate(user);
        chatPrivate.CreateGUI();
    }

    @Override
    public void windowClosing(WindowEvent e) {
        if (_sck == null) {
            System.exit(1);
            return;
        }
        Signout();
    }

    private void Signout() {
        try {
            Message sendToServer = new Message();
            sendToServer.setMessage(_jtxtUsername.getText());
            sendToServer.setStatus(MessageType.USER_OFFLINE);
            if (_sck != null) {
                StreamData.WriteObject(_oos, sendToServer);
                StreamData.CloseStream(_oos, _ois);
                t.interrupt();
            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }

    }

    class ClientHandler extends Thread {

        @Override
        public void run() {
            try {
                Message serverMessage;
                while ((serverMessage = (Message) _ois.readObject()) != null) {
                    _jtxtChatContent.append(serverMessage.getMessage() + "\n");
                }
            } catch (Exception e) {
                Signout();
                e.printStackTrace();
            }

        }
    }
}
